package com.example.mysql.entity;

import java.io.Serial;
import java.lang.Boolean;
import java.util.Date;

import com.baomidou.mybatisplus.annotation.*;

import java.io.Serializable;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;

/**
 * 用户表(User)表实体类
 *
 * @author 龙茶清欢
 * @since 2024-09-24 15:58:41
 */
@Getter
@Setter
@TableName("t_user")
public class User implements Serializable {
    @Serial
    private static final long serialVersionUID = 521606995550349734L;

    @TableId(value = "user_id", type = IdType.ASSIGN_ID)
    private Long userId;

    // 该注解用于标记实体类中的非主键字段，它告诉 MyBatis-Plus 如何映射实体类字段到数据库表字段。
    // 如果你的实体类字段名遵循驼峰命名规则，并且与数据库表字段名一致，你可以省略这个注解。
    // 此处两者命名一致，可以省略
    @TableField(value = "username")
    private String username;

    // select 指示在执行查询操作时，该字段是否应该包含在 SELECT 语句中。这个属性允许您控制查询结果中包含哪些字段，从而提供更细粒度的数据访问控制。
    @TableField(value = "password", select = false)
    private String password;

    // 该注解用于指定实体类中的字段在执行查询操作时的默认排序方式。通过在实体类字段上使用@OrderBy注解，可以确保在执行查询时，
    // 如果没有显式指定排序条件，MyBatis-Plus 将按照注解中定义的排序规则返回结果。
    // @OrderBy注解的asc属性用于指定排序是否为升序，如果设置为true，则表示升序排序；如果设置为false，则表示降序排序。
    // sort属性用于指定排序规则的优先级，数字越小，优先级越高，即越先被应用。
    @OrderBy(asc = false, sort = 10) // 指定默认排序为倒序，优先级为10
    private Integer age;

    @TableField(value = "gender")
    private Gender gender; // 假设 Gender 是一个枚举类型

    // 指定数据库中的字段名。如果你的实体类字段名与数据库字段名不同，使用这个属性来指定正确的数据库字段名。
    // 此处两者命名不一致，需要指定
    @TableField(value = "nick_name") // 映射到数据库字段 "nick_name"
    private String nickName;

    // 指示这个字段是否存在于数据库表中。如果设置为 false，MyBatis-Plus 在生成 SQL 时会忽略这个字段。默认值： true
    @TableField(exist = false)
    private String avatar;

    // 乐观锁是一种并发控制机制，用于确保在更新记录时，该记录未被其他事务修改。MyBatis-Plus 提供了 OptimisticLockerInnerInterceptor 插件，使得在应用中实现乐观锁变得简单。
    // 要使用乐观锁插件，需要进行两步配置： 1. 配置乐观所插锁插件，2. 在对应实体类字段上添加 @Version 注解
    @Version
    private Integer version;

    @TableField(value = "email")
    private String email;

    @TableField(value = "birthday")
    private Date birthday;

    @TableField(value = "mobile")
    private String mobile;

    @TableField(value = "description")
    private String description;

    @TableField(value = "login_count")
    private Integer loginCount;

    @TableField(value = "last_login_time")
    private Date lastLoginTime;

    @TableField(value = "last_login_ip")
    private String lastLoginIp;

    @TableField(value = "ip_source")
    private String ipSource;

    @TableField(value = "browser")
    private String browser;

    @TableField(value = "os")
    private String os;

    @TableField(value = "salt")
    private String salt;

    @TableField(value = "status")
    private Boolean status;

    // 该注解用于标记实体类中的字段作为逻辑删除字段。逻辑删除是一种数据管理策略，它不是真正地从数据库中删除记录，
    // 而是在记录中标记该记录为已删除状态。通过使用@TableLogic注解，MyBatis-Plus 可以在查询、更新和删除操作中自动处理逻辑删除字段的值。
    @TableLogic
    private Boolean delFlag;

    @TableField(value = "create_time", fill = FieldFill.INSERT)
    private Date createTime;

    @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;

    @TableField(value = "create_by")
    private String createBy;

    @TableField(value = "update_by")
    private String updateBy;

    @Getter
    @RequiredArgsConstructor
    public enum Gender {
        MALE("M", "男"),
        FEMALE("F", "女");

        // 自动映射枚举，参考 mybatis-plus 官网 https://baomidou.com/guides/auto-convert-enum/
        // 该注解用于标记枚举类中的字段，指定在数据库中存储的枚举值。当实体类中的某个字段是枚举类型时，
        // 使用@EnumValue注解可以告诉MyBatis-Plus在数据库中存储枚举值的哪个属性。
        @EnumValue // 指定存储到数据库的枚举值为 code
        private final String code;
        private final String description;
    }
}

// MyBatisPlus 注解的用法及属性使用参考官网 https://baomidou.com/reference/annotation/
